package com.sunyur.tailor.channel.service.inner.category.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.google.common.collect.Lists;
import com.sunyur.tailor.channel.common.inner.base.SunyurListResult;
import com.sunyur.tailor.channel.common.inner.base.SunyurResult;
import com.sunyur.tailor.channel.common.inner.util.SunyurClientUtil;
import com.sunyur.tailor.channel.common.inner.util.SunyurResultUtil;
import com.sunyur.tailor.channel.common.middle.base.ChannelListResult;
import com.sunyur.tailor.channel.common.middle.base.ChannelResult;
import com.sunyur.tailor.channel.common.middle.enums.MiddleResultEnum;
import com.sunyur.tailor.channel.common.middle.util.ChannelListResultUtil;
import com.sunyur.tailor.channel.common.middle.util.ChannelResultUtil;
import com.sunyur.tailor.channel.service.inner.category.model.*;
import com.sunyur.tailor.channel.service.inner.category.param.*;
import com.sunyur.tailor.channel.service.inner.category.service.SunyurCategoryService;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName SunyurCategoryServiceImpl
 * @Description 分类接口
 * @Author hao.tian
 * @Date 2021/5/20
 * @Version v1.0
 */
@Service("sunyurCategoryService")
public class SunyurCategoryServiceImpl implements SunyurCategoryService {

    private static final Logger LOGGER_INFO = LoggerFactory.getLogger(SunyurCategoryServiceImpl.class);
    private static final Logger LOGGER_ERROR = LoggerFactory.getLogger(SunyurCategoryServiceImpl.class);

    /**
     * 请求商越Client
     */
    @Autowired
    private SunyurClientUtil sunyurClient;

    /**
     * 批量添加类目接口 链接
     */
    @Value("${sunyur.api.batchCreateCategory}")
    private String batchCreateCategory;

    /**
     * 批量获取类目接口 链接
     */
    @Value("${sunyur.api.listCategory}")
    private String listCategory;

    /**
     * 批量获取物料通过修改时间接口 链接
     */
    @Value("${sunyur.api.listCategoryByModifyTime}")
    private String listCategoryByModifyTime;

    /**
     * 批量获取商城类目(通过内部商城分类编码)接口 链接
     */
    @Value("${sunyur.api.listCategoryBySystemCode}")
    private String listCategoryBySystemCode;

    /**
     * 批量获取商城类目(通过内部商城分类编码)接口 链接
     */
    @Value("${sunyur.api.listCategoryByParam}")
    private String listCategoryByParam;

    /**
     * @Author pengbing
     * @Description 批量添加后台类目
     * @WIKI 09-批量添加后台类目【已上线】   http://doc.sunyur.com/pages/viewpage.action?pageId=61309120
     * @Date 15:15 2021/7/9
     * @Param [createCategoryParamList]
     * @return com.sunyur.tailor.channel.common.middle.base.ChannelResult
     **/
    @Override
    public ChannelResult createCategory(List<CreateCategoryParam> createCategoryParamList) throws Exception {
        LOGGER_INFO.info("SunyurCategoryServiceImpl createCategory param is {}", JSON.toJSONString(createCategoryParamList));
        if (ObjectUtils.isEmpty(createCategoryParamList)) {
            return ChannelResultUtil.error(MiddleResultEnum.PARAM_NULL.getCode(), "SunyurCategoryServiceImpl createCategory param is null");
        }
        // 如果是第一级分类则parent编码与code的编码值一致
        for (CreateCategoryParam createCategoryParam : createCategoryParamList) {
            if (ObjectUtils.isEmpty(createCategoryParam)) {
                if (createCategoryParam.getLevel() == 0 && !createCategoryParam.getParentCategoryCode().equals(createCategoryParam.getCategoryCode())) {
                    return ChannelResultUtil.error(MiddleResultEnum.PARAM_ERROR.getCode(), "第一级分类parentCategoryCode编码需与categoryCode的编码值一致" + "parentCategoryCode:" + createCategoryParam.getParentCategoryCode() + "categoryCode:" + createCategoryParam.getCategoryCode());
                }
            }
        }
         // 参数按长度分割
        List<List<CreateCategoryParam>> categoryList = Lists.partition(createCategoryParamList, 20);
        // 错误信息List
        List<String> errorMsgList = Lists.newArrayList();
        for (List<CreateCategoryParam> createCategoryParams : categoryList) {
            // 调用主线接口
            SunyurResult sunyurResult = sunyurClient.execPost(batchCreateCategory, JSON.toJSONString(createCategoryParams), null);
            if (!SunyurResultUtil.isSuccess(sunyurResult)) {
                LOGGER_ERROR.error("createCategory loop call sunyur request fail, param is {}, result is {}", JSON.toJSONString(createCategoryParams), JSON.toJSONString(sunyurResult));
                // 每批次错误信息收集
                errorMsgList.add(sunyurResult.getContent() + "-" + sunyurResult.getErrorMessage());
            }
        }
        // 存在错误信息
        if (!CollectionUtils.isEmpty(errorMsgList)) {
           return ChannelResultUtil.error(MiddleResultEnum.FAILED.getCode(), JSON.toJSONString(errorMsgList));
        }
        return ChannelResultUtil.success(null);
    }

    /**
     * @Author pengbing
     * @Description 批量获取物料类目(一二三级)
     * @WIKI 13-批量获取物料类目(一二三级)【已上线】   http://doc.sunyur.com/pages/viewpage.action?pageId=66388159
     * @Date 15:15 2021/7/9
     * @Param [createCategoryParamList]
     * @return com.sunyur.tailor.channel.common.middle.base.ChannelResult
     **/
    @Override
    public ChannelResult<List<ListCategoryModel>> listCategory(ListCategoryParam listCategoryParam) throws Exception {
        LOGGER_INFO.info("SunyurCategoryServiceImpl listCategory param is {}", JSON.toJSONString(listCategoryParam));
        if (ObjectUtils.isEmpty(listCategoryParam)) {
            return ChannelResultUtil.error(MiddleResultEnum.PARAM_NULL.getCode(), "SunyurCategoryServiceImpl listCategory param is null");
        }
        List<ListCategoryModel> resultList=new ArrayList<>();
        List<List<Long>> categoryIdList=Lists.partition(listCategoryParam.getCategoryIds(),20);
        // 错误信息List
        List<String> errorMsgList = Lists.newArrayList();
        ListCategoryParam listCategoryParamClient = new ListCategoryParam();
        TypeReference<SunyurResult<List<ListCategoryModel>>> typeReference = new TypeReference<SunyurResult<List<ListCategoryModel>>>() {
        };
        for (List<Long> longs : categoryIdList) {
            listCategoryParamClient.setCategoryIds(longs);
            // 调用主线接口
            SunyurResult<List<ListCategoryModel>> sunyurResult = sunyurClient.execPost(listCategory, JSON.toJSONString(listCategoryParamClient), typeReference);
            if (SunyurResultUtil.isSuccess(sunyurResult)) {
                resultList.addAll(sunyurResult.getContent());
            } else {
                LOGGER_ERROR.error("listMateriel loop call sunyur request fail, param is {}, result is {}", JSON.toJSONString(listCategoryParamClient), JSON.toJSONString(sunyurResult));
                // 每批次错误信息收集
                errorMsgList.add(sunyurResult.getContent() + "-" + sunyurResult.getErrorMessage());
            }
        }
        // 存在错误信息
        if (!CollectionUtils.isEmpty(errorMsgList)) {
            return ChannelResultUtil.error(MiddleResultEnum.FAILED.getCode(), JSON.toJSONString(errorMsgList));
        }
        return ChannelResultUtil.success(resultList);
    }

    /**
     * @Author pengbing
     * @Description 批量获取物料分类通过修改时间
     * @WIKI 26-批量获取物料分类通过修改时间   http://doc.sunyur.com/pages/viewpage.action?pageId=117964879
     * @Date 15:15 2021/7/9
     * @Param [createCategoryParamList]
     * @return com.sunyur.tailor.channel.common.middle.base.ChannelResult
     **/
    @Override
    public ChannelListResult<ListCategoryByModifyTimeModel> listCategoryByModifyTime(ListCategoryByModifyTimeParam listCategoryByModifyTimeParam) throws Exception {
        LOGGER_INFO.info("SunyurCategoryServiceImpl listCategoryByModifyTime param is {}", JSON.toJSONString(listCategoryByModifyTimeParam));
        if (ObjectUtils.isEmpty(listCategoryByModifyTimeParam)) {
            return ChannelListResultUtil.error(MiddleResultEnum.PARAM_NULL.getCode(), "SunyurCategoryServiceImpl listCategoryByModifyTime param is null");
        }
        if (ObjectUtils.isEmpty(listCategoryByModifyTimeParam.getPage())) {
            listCategoryByModifyTimeParam.setPage(0);
        }
        if (listCategoryByModifyTimeParam.getPageSize() > 100 || ObjectUtils.isEmpty(listCategoryByModifyTimeParam.getPageSize())) {
            listCategoryByModifyTimeParam.setPageSize(100);
        }
        // 调用主线接口
        TypeReference<SunyurListResult<ListCategoryByModifyTimeModel>> typeReference = new TypeReference<SunyurListResult<ListCategoryByModifyTimeModel>>() {
        };
        SunyurListResult<ListCategoryByModifyTimeModel> sunyurListResult = sunyurClient.execListPost(listCategoryByModifyTime, JSON.toJSONString(listCategoryByModifyTimeParam), typeReference);
        // 主线报错
        if (!SunyurResultUtil.isSuccess(sunyurListResult)) {
            return ChannelListResultUtil.error(MiddleResultEnum.FAILED.getCode(), sunyurListResult.getErrorMessage());
        }
        // 判断是否存在下一页
        if (!SunyurResultUtil.isNextPage(sunyurListResult)) {
            return ChannelListResultUtil.success(sunyurListResult.getContent());
        }

        // 返回结果集
        List<ListCategoryByModifyTimeModel> resultList = Lists.newArrayList();
        // 将第一次查询的结果收集
        resultList.addAll(sunyurListResult.getContent());
        // 循环查询剩余数据
        for (int i = 0; i < sunyurListResult.getTotalPage(); i++) {
            listCategoryByModifyTimeParam.setPage(i + 1);
            // 调用主线接口
            SunyurListResult<ListCategoryByModifyTimeModel> sunyurPageResult = sunyurClient.execListPost(listCategoryByModifyTime, JSON.toJSONString(listCategoryByModifyTimeParam), typeReference);
            // 某次调用主线返回错误（小概率，可能网络等原因，此时结果集数据不完整，本次查询失败）
            if (!SunyurResultUtil.isSuccess(sunyurPageResult)) {
                LOGGER_ERROR.error("listCategoryByModifyTime loop call sunyur request fail, param is {}, result is {}", JSON.toJSONString(listCategoryByModifyTimeParam), JSON.toJSONString(sunyurPageResult));
                return ChannelListResultUtil.error(MiddleResultEnum.FAILED.getCode(), sunyurPageResult.getErrorMessage());
            }
            resultList.addAll(sunyurPageResult.getContent());
        }
        return ChannelListResultUtil.success(resultList);
    }

    /**
     * @Author pengbing
     * @Description 获取商城分类通过【内部商城分类编码】
     * @WIKI 32-获取商城分类通过【内部商城分类编码】   http://doc.sunyur.com/pages/viewpage.action?pageId=160661683
     * @Date 15:15 2021/7/9
     * @Param [createCategoryParamList]
     * @return com.sunyur.tailor.channel.common.middle.base.ChannelResult
     **/
    @Override
    public ChannelResult<List<ListCategoryBySystemCodeModel>> listCategoryBySystemCode(ListCategoryBySystemCodeParam listCategoryBySystemCodeParam) throws Exception {
        LOGGER_INFO.info("SunyurCategoryServiceImpl listCategoryBySystemCode param is {}", JSON.toJSONString(listCategoryBySystemCodeParam));
        if (ObjectUtils.isEmpty(listCategoryBySystemCodeParam)) {
            return ChannelResultUtil.error(MiddleResultEnum.PARAM_NULL.getCode(), "SunyurCategoryServiceImpl listCategoryBySystemCode param is null");
        }
        List<ListCategoryBySystemCodeModel> resultList = Lists.newArrayList();
        // 参数按长度分割
        List<List<String>> systemCategoryCodeList = Lists.partition(listCategoryBySystemCodeParam.getSystemCategoryCodeList(), 100);
        // 错误信息List
        List<String> errorMsgList = Lists.newArrayList();
        ListCategoryBySystemCodeParam listCategoryBySystemCodeParamClient = new ListCategoryBySystemCodeParam();
        TypeReference<SunyurResult<List<ListCategoryBySystemCodeModel>>> typeReference = new TypeReference<SunyurResult<List<ListCategoryBySystemCodeModel>>>() {
        };
        for (List<String> strings : systemCategoryCodeList) {
            listCategoryBySystemCodeParamClient.setSystemCategoryCodeList(strings);
            // 调用主线接口
            SunyurResult<List<ListCategoryBySystemCodeModel>> sunyurResult = sunyurClient.execPost(listCategoryBySystemCode, JSON.toJSONString(listCategoryBySystemCodeParamClient), typeReference);
            if (SunyurResultUtil.isSuccess(sunyurResult)) {
                resultList.addAll(sunyurResult.getContent());
            } else {
                LOGGER_ERROR.error("listCategoryBySystemCode loop call sunyur request fail, param is {}, result is {}", JSON.toJSONString(listCategoryBySystemCodeParamClient), JSON.toJSONString(sunyurResult));
                // 每批次错误信息收集
                errorMsgList.add(sunyurResult.getContent() + "-" + sunyurResult.getErrorMessage());
            }
        }
        // 存在错误信息
        if (!CollectionUtils.isEmpty(errorMsgList)) {
           return ChannelResultUtil.error(MiddleResultEnum.FAILED.getCode(), JSON.toJSONString(errorMsgList));
        }
        return ChannelResultUtil.success(resultList);
    }

    /**
     * @Author pengbing
     * @Description 批量获取商城分类
     * @WIKI 33-批量获取商城分类   http://doc.sunyur.com/pages/viewpage.action?pageId=167215185
     * @Date 15:15 2021/7/9
     * @Param [createCategoryParamList]
     * @return com.sunyur.tailor.channel.common.middle.base.ChannelResult
     **/
    @Override
    public ChannelListResult<ListCategoryByParamModel> listCategoryByParam(ListCategoryByParamParam listCategoryByParamParam) throws Exception {
        LOGGER_INFO.info("SunyurCategoryServiceImpl listCategoryByParam param is {}", JSON.toJSONString(listCategoryByParamParam));
        if (ObjectUtils.isEmpty(listCategoryByParamParam)) {
            return ChannelListResultUtil.error(MiddleResultEnum.PARAM_NULL.getCode(), "SunyurCategoryServiceImpl listCategoryByParam param is null");
        }
        if (listCategoryByParamParam.getPageSize() > 100 || ObjectUtils.isEmpty(listCategoryByParamParam.getPageSize())) {
            listCategoryByParamParam.setPageSize(100);
        }
        if (ObjectUtils.isEmpty(listCategoryByParamParam.getPage())) {
            listCategoryByParamParam.setPage(0);
        }
        // 调用主线接口
        TypeReference<SunyurListResult<ListCategoryByParamModel>> typeReference = new TypeReference<SunyurListResult<ListCategoryByParamModel>>() {
        };
        SunyurListResult<ListCategoryByParamModel> sunyurListResult = sunyurClient.execListPost(listCategoryByParam, JSON.toJSONString(listCategoryByParamParam), typeReference);
        // 主线报错
        if (!SunyurResultUtil.isSuccess(sunyurListResult)) {
            return ChannelListResultUtil.error(MiddleResultEnum.FAILED.getCode(), sunyurListResult.getErrorMessage());
        }
        // 判断是否存在下一页
        if (!SunyurResultUtil.isNextPage(sunyurListResult)) {
            return ChannelListResultUtil.success(sunyurListResult.getContent());
        }

        // 返回结果集
        List<ListCategoryByParamModel> resultList = Lists.newArrayList();
        // 将第一次查询的结果收集
        resultList.addAll(sunyurListResult.getContent());
        // 循环查询剩余数据
        for (int i = 0; i < sunyurListResult.getTotalPage(); i++) {
            listCategoryByParamParam.setPage(i + 1);
            // 调用主线接口
            SunyurListResult<ListCategoryByParamModel> sunyurPageResult = sunyurClient.execListPost(listCategoryByParam, JSON.toJSONString(listCategoryByParamParam), typeReference);
            // 某次调用主线返回错误（小概率，可能网络等原因，此时结果集数据不完整，本次查询失败）
            if (!SunyurResultUtil.isSuccess(sunyurPageResult)) {
                LOGGER_ERROR.error("listCategoryByParam loop call sunyur request fail, param is {}, result is {}", JSON.toJSONString(listCategoryByParamParam), JSON.toJSONString(sunyurPageResult));
                return ChannelListResultUtil.error(MiddleResultEnum.FAILED.getCode(), sunyurPageResult.getErrorMessage());
            }
            resultList.addAll(sunyurPageResult.getContent());
        }
        return ChannelListResultUtil.success(resultList);
    }
}
